// addrspace.h 
//	Data structures to keep track of executing user programs 
//	(address spaces).
//
//	For now, we don't keep any information about address spaces.
//	The user level CPU state is saved and restored in the thread
//	executing the user program (see thread.h).
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef ADDRSPACE_H
#define ADDRSPACE_H

#include "copyright.h"
#include "filesys.h"
#include "table.h"
#include "P2Defs.h"

#include "IPTManager.h"
#include "IPTEntry.h"

#define UserStackSize 1024 	// increase this as necessary!

#define MaxOpenFiles 256
#define MaxChildSpaces 256

class AddrSpace {
public:
   
    ~AddrSpace(); // De-allocate an address space

    void InitRegisters(); // Initialize user-level CPU registers,
    // before jumping to user code

    void SaveState(); // Save/restore address space-specific
    void RestoreState(); // info on a context switch
    Table fileTable; // Table of openfiles

    IPTEntry *pageTable;

    int stackStartVpn; //keeps tack of where a user-stack start from
    Lock* addrLock; // for ME access

   // Semaphore* mutex ;
    
    int numPages; // Number of pages in the virtual
    // address space

    AddrSpace();
    AddrSpace(OpenFile* exe) ;
    
    int CreateNewStack(int); // creats a new stack
    int DestroyStack(int); // deallocates the user-stack
    int EnsurePageTable(int); // makes a new page table with larger size
    void printPageTable(); //print-outs the page table

    int pid;
    OpenFile *exeFile; // handle for the exetuable file.

    int clockIndex;
    TranslationEntry* tlbCache;

    // Called on a new user program loaded.
    int LoadForVM(OpenFile *executable);

    // called on the pagefaultexception
    void LoadAddress(int);
    void TLBSwap(int oldPage, IPTEntry *newEntry);
    int loadPageInMemory(int ppn, int vmAddress);

    // called when my page is swapped out in a swap-file
    int markPageAsEvicted(int vpn, int swapLoc , int ppn, bool isDirty_);

    void onOtherException();

    int onProcessEnded() ;
};

#endif // ADDRSPACE_H
